package com.mes.cloud.service;

import com.mes.cloud.api.dto.request.organization.BaseChannelCustomerRequest;
import com.mes.cloud.api.dto.request.organization.BaseChannelRequest;
import com.mes.cloud.api.dto.request.organization.BaseChannelVoRequest;
import com.mes.cloud.api.dto.request.organization.SysOrganizationChannelRequest;
import com.mes.cloud.api.dto.request.position.SysPositionChannelTypeRequest;
import com.mes.cloud.api.dto.response.BaseChannelDto;
import com.mes.cloud.exception.BaseException;
import com.mes.cloud.common.JsonResult;
import com.mes.cloud.constant.Constants;
import com.mes.cloud.dao.BaseChannelDao;
import com.mes.cloud.entity.BaseChannel;
import com.mes.cloud.entity.SysOrganizationChannel;
import com.mes.cloud.entity.SysPositionChannelType;
import com.mes.cloud.entity.vo.organization.BaseChannelVo;
import com.mes.cloud.enums.HttpStatusEnum;
import com.mes.cloud.util.DateUtil;
import com.mes.cloud.util.UserUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 渠道定义
 *
 * @author ysd
 * @version 2019-08-20 15:48:07
 * @email shaodong.yuan@pactera.com
 */
@Service
public class BaseChannelService {

    private BaseChannelDao baseChannelDao;
    private IPKeyGenerator iPKeyGenerator;
    private SysCodeGeneratorService sysCodeGeneratorService;

    @Autowired
    public BaseChannelService(BaseChannelDao baseChannelDao,
                              IPKeyGenerator iPKeyGenerator,
                              SysCodeGeneratorService sysCodeGeneratorService) {
        this.baseChannelDao = baseChannelDao;
        this.iPKeyGenerator = iPKeyGenerator;
        this.sysCodeGeneratorService = sysCodeGeneratorService;
    }

    /**
     * 查所有渠道
     *
     * @param baseChannelRequest
     * @return JsonResult
     */
    public JsonResult<List<BaseChannelDto>> list(BaseChannelVoRequest baseChannelRequest) {
        JsonResult<List<BaseChannelDto>> jsonResult = new JsonResult<>();
        //查询条件
        BaseChannel selectParam = new BaseChannel();
        BeanUtils.copyProperties(baseChannelRequest, selectParam);
        //引用获取启用状态的数据
        selectParam.setEnableFlag(Constants.ENABLE_FLAG_YES);
        List<BaseChannel> baseChannelList = baseChannelDao.findAllBassChannel(selectParam);
        List<BaseChannelDto> baseChannelDtoList = new ArrayList<>();
        for (BaseChannel baseChannel : baseChannelList) {
            BaseChannelDto baseChannelDto = new BaseChannelDto();
            BeanUtils.copyProperties(baseChannel, baseChannelDto);
            baseChannelDtoList.add(baseChannelDto);
        }
        return jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(baseChannelDtoList);
    }

    /**
     * 查所有渠道（关联岗位）
     *
     * @return JsonResult
     */
    public JsonResult<List<BaseChannelDto>> findListByPositionId(SysPositionChannelTypeRequest sysPositionChannelTypeRequest) {
        //查询条件
        SysPositionChannelType selectParam = new SysPositionChannelType();
        BeanUtils.copyProperties(sysPositionChannelTypeRequest, selectParam);
        return uniqueBassChannel(baseChannelDao.findAllChannelByPositId(selectParam));
    }

    /**
     * 查所有渠道（关联组织）
     *
     * @return JsonResult
     */
    public JsonResult<List<BaseChannelDto>> findListByOrganizationId(SysOrganizationChannelRequest sysOrganizationChannelRequest) {
        //查询条件
        SysOrganizationChannel selectParam = new SysOrganizationChannel();
        BeanUtils.copyProperties(sysOrganizationChannelRequest, selectParam);
        return uniqueBassChannel(baseChannelDao.findAllChannelByOragId(selectParam));
    }

    /**
     * @Author ysd
     * @Description 查所有渠道（关联客户）
     * @Date 15:18 2019/9/26
     **/
    public JsonResult<List<BaseChannelDto>> findCustomerChannelListByIds(BaseChannelCustomerRequest customerChannelRequest) {
        JsonResult jsonResult = new JsonResult();
        //查询条件
        List<BaseChannelVo> channelDetails = baseChannelDao.findCustomerChannelListByIds(customerChannelRequest);
        List<BaseChannelDto> baseChannelDtoList = new ArrayList<>();
        for (BaseChannelVo baseChannelVo : channelDetails) {
            BaseChannelDto baseChannelDto = new BaseChannelDto();
            BeanUtils.copyProperties(baseChannelVo, baseChannelDto);
            baseChannelDtoList.add(baseChannelDto);
        }
        return jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(baseChannelDtoList);
    }

    /**
     * @Author ysd
     * @Description 网络覆盖区域_渠道属性
     * @Date 16:46 2019/9/21
     */
    public JsonResult<List<BaseChannelDto>> findCustomerChannelType(List<String> channelIds) {
        JsonResult jsonResult = new JsonResult();
        //查询条件
        List<BaseChannelVo> channelDetails = baseChannelDao.findCustomerChannelType(channelIds);
        List<BaseChannelDto> baseChannelDtoList = new ArrayList<>();
        for (BaseChannelVo baseChannelVo : channelDetails) {
            BaseChannelDto baseChannelDto = new BaseChannelDto();
            BeanUtils.copyProperties(baseChannelVo, baseChannelDto);
            baseChannelDtoList.add(baseChannelDto);
        }
        return jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(baseChannelDtoList);
    }

    /**
     * @Author ysd
     * @Description 客户详情_渠道树
     * @Date 16:46 2019/9/21
     */
    public JsonResult<List<BaseChannelDto>> findChannelListByCustomerId(List<String> channelIds) {
        JsonResult jsonResult = new JsonResult();

        //所有启用状态
        BaseChannel selectParam = new BaseChannel();
        selectParam.setEnableFlag(Constants.ENABLE_FLAG_YES);
        List<BaseChannel> baseChannelList = baseChannelDao.findAllBassChannel(selectParam);
        //客户已关联渠道（包含停用渠道）
        if (!CollectionUtils.isEmpty(channelIds)) {
            List<BaseChannel> channelDetails = baseChannelDao.findChannelListByCustomerId(channelIds);
            if (channelDetails != null && channelDetails.size() > 0) {
                //已关联渠道 - 所有启用渠道 = 关联已停用的渠道
                channelDetails.removeAll(baseChannelList);
                //所有启用渠道 + 关联已停用渠道 = 当前客户显示渠道树
                baseChannelList.addAll(channelDetails);
            }
        }
        //转换类型
        List<BaseChannelDto> baseChannelDtoList = new ArrayList<>();
        for (BaseChannel baseChannel : baseChannelList) {
            BaseChannelDto baseChannelDto = new BaseChannelDto();
            BeanUtils.copyProperties(baseChannel, baseChannelDto);
            baseChannelDtoList.add(baseChannelDto);
        }
        return jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(baseChannelDtoList);

    }

    /**
     * 新增
     *
     * @param baseChannelRequest
     * @return JsonResult
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<BaseChannelDto> add(BaseChannelRequest baseChannelRequest) {
        JsonResult jsonResult = new JsonResult();
        BaseChannel baseChannel = new BaseChannel();
        BeanUtils.copyProperties(baseChannelRequest, baseChannel);
        //设置层级
        if (Constants.CHANNEL_DIRECTORY_PARENTID.equals(baseChannel.getParentId())) {
            baseChannel.setModuleLevel(1);
        } else {
            BaseChannel baseChan = baseChannelDao.selectByPrimaryKey(baseChannel.getParentId());
            baseChannel.setModuleLevel(baseChan.getModuleLevel() + 1);
        }

        if (baseChannel.getModuleLevel() > Constants.BASE_CHANNEL_MODULELEVEL_MAX) {
            jsonResult.setMsg(HttpStatusEnum.BASE_CHANNEL_MODULELEVEL_ERROR.getMessage()).setCode(HttpStatusEnum.BASE_CHANNEL_MODULELEVEL_ERROR.getCode());
            return jsonResult;
        }
        baseChannel.setId(iPKeyGenerator.getGenerateKey());
        baseChannel.setCode(sysCodeGeneratorService.getCode(Constants.BASE_CHANNEL_PREFIX));
        baseChannel.setUpdateDateStr(DateUtil.updateDateStr());
        baseChannel.setCreateBy(UserUtil.getCreateByName());
        baseChannel.setUpdateBy(UserUtil.getUpdateByName());
        baseChannel.setCreateByNo(UserUtil.getCreateByNo());
        baseChannel.setUpdateByNo(UserUtil.getUpdateByNo());
        int count = baseChannelDao.insertSelective(baseChannel);

        //响应值
        BaseChannel baseChannel1 = baseChannelDao.selectByPrimaryKey(baseChannel.getId());
        BaseChannelDto baseChannelDto = new BaseChannelDto();
        BeanUtils.copyProperties(baseChannel1, baseChannelDto);

        if (count > 0) {
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(baseChannelDto);
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(), HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }

    /**
     * 更新
     *
     * @param baseChannelRequest
     * @return JsonResult
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult update(BaseChannelRequest baseChannelRequest) {
        JsonResult jsonResult = new JsonResult();

        BaseChannel baseChannel = new BaseChannel();
        BeanUtils.copyProperties(baseChannelRequest, baseChannel);
        baseChannel.setUpdateDateStr(DateUtil.updateDateStr());
        baseChannel.setUpdateBy(UserUtil.getUpdateByName());
        baseChannel.setUpdateByNo(UserUtil.getUpdateByNo());
        int count = baseChannelDao.updateByPrimaryKeySelective(baseChannel);

        if (count == 1) {
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
            jsonResult.setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(), HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }

    /**
     * 查看详情
     *
     * @param id
     * @return JsonResult
     */
    public JsonResult<BaseChannelDto> get(String id) {
        JsonResult jsonResult = new JsonResult();
        BaseChannel baseChannel = baseChannelDao.selectByPrimaryKey(id);
        if (baseChannel == null) {
            return jsonResult.setCode(HttpStatusEnum.RECORD_NOT_EXIST.getCode()).setMsg(HttpStatusEnum.RECORD_NOT_EXIST.getMessage());
        }
        BaseChannelDto baseChannelDto = new BaseChannelDto();
        BeanUtils.copyProperties(baseChannel, baseChannelDto);
        return jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(baseChannelDto);
    }

    /**
     * 禁用启用
     *
     * @param id
     * @param enableFlag
     * @return JsonResult
     */
    public JsonResult updateEnableFlag(String id, String enableFlag) {
        JsonResult jsonResult = new JsonResult();
        BaseChannel baseChannel = new BaseChannel();
        //停用校验子节点状态
        if (Constants.ENABLE_FLAG_NO.equals(enableFlag)) {
            //查询启用状态子节点数
            BaseChannel selectParam = new BaseChannel();
            selectParam.setParentId(id);
            selectParam.setEnableFlag(Constants.ENABLE_FLAG_YES);
            int size = baseChannelDao.selectCount(selectParam);
            if (size > 0) {
                jsonResult.setMsg(HttpStatusEnum.BASE_CHANNEL_ENABLEFLAG_ERROR.getMessage()).setCode(HttpStatusEnum.BASE_CHANNEL_ENABLEFLAG_ERROR.getCode());
                return jsonResult;
            }
        }

        baseChannel.setId(id);
        baseChannel.setEnableFlag(enableFlag.toString());
        baseChannel.setUpdateDateStr(DateUtil.updateDateStr());
        baseChannel.setUpdateBy(UserUtil.getUpdateByName());
        baseChannel.setUpdateByNo(UserUtil.getUpdateByNo());
        int count = baseChannelDao.updateByPrimaryKeySelective(baseChannel);
        if (count == 1) {
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
            jsonResult.setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(), HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }

    /**
     * @Author ysd
     * @Description 数据去重
     * @Date 10:06 2019/9/5
     **/
    private JsonResult<List<BaseChannelDto>> uniqueBassChannel(List<BaseChannel> selectList) {
        JsonResult<List<BaseChannelDto>> jsonResult = new JsonResult<>();
        //转换类型
        List<BaseChannelDto> baseChannelDtoList = new ArrayList<>();
        //查询所有启用状态
        BaseChannel selectParam = new BaseChannel();
        selectParam.setEnableFlag(Constants.ENABLE_FLAG_YES);
        selectParam.setModuleLevel(Constants.BASE_CHANNEL_MODULELEVEL_1);
        List<BaseChannel> baseChannelList = baseChannelDao.findAllBassChannel(selectParam);

        if (baseChannelList != null && baseChannelList.size() > 0) {
            //去重
            selectList.removeAll(baseChannelList);
            baseChannelList.addAll(selectList);
        }
        for (BaseChannel baseChannel : baseChannelList) {
            BaseChannelDto baseChannelDto = new BaseChannelDto();
            BeanUtils.copyProperties(baseChannel, baseChannelDto);
            baseChannelDtoList.add(baseChannelDto);
        }
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(baseChannelDtoList);
        return jsonResult;
    }

    /**
     * 查询下级客户类型
     *
     * @param channelIds
     * @return JsonResult<List<String>>
     */
    public JsonResult<List<String>> findChildrenCustomerType(List<String> channelIds) {
        JsonResult<List<String>> jsonResult = new JsonResult<>();
        List<String> customerTypes = baseChannelDao.findChildrenCustomerType(channelIds);
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(customerTypes);
        return jsonResult;
    }

    /**
     * 查询上级客户类型
     *
     * @param channelId
     * @return JsonResult<List<String>>
     */
    public JsonResult<List<String>> findParentCustomerType(List<String> channelId) {
        JsonResult<List<String>> jsonResult = new JsonResult<>();
        List<String> customerTypes = baseChannelDao.findParentCustomerType(channelId);
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(customerTypes);
        return jsonResult;
    }

    /**
     * 通过ids集合查询获得上级渠道id集合
     *
     * @param channelIds
     * @return JsonResult<List<String>>
     */
    public JsonResult<List<String>> findChannelIdsByIds(List<String> channelIds) {
        JsonResult<List<String>> jsonResult = new JsonResult<>();
        List<String> ids = baseChannelDao.findChannelIdsByIds(channelIds);
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(ids);
        return jsonResult;
    }

    public JsonResult<List<BaseChannelDto>> findChannelByIds(Set<String> setChanelId) {
        List<BaseChannel> baseChannelList = baseChannelDao.findChannelByIds(setChanelId);
        List<BaseChannelDto> baseChannelDtoList = new ArrayList<>();
        for (BaseChannel baseChannel : baseChannelList) {
            BaseChannelDto baseChannelDto = new BaseChannelDto();
            BeanUtils.copyProperties(baseChannel, baseChannelDto);
            baseChannelDtoList.add(baseChannelDto);
        }
        JsonResult<List<BaseChannelDto>> jsonResult = new JsonResult<>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(baseChannelDtoList);
        return jsonResult;
    }

    /**
     * <查询子节点>
     *
     * @param id
     * @return com.shinho.tntframe.core.common.model.JsonResult<java.util.List<java.lang.String>>
     * @author xy
     * @date 2019/10/11 10:46
     */
    public JsonResult<List<String>> findChildrenIdsById(String id) {
        JsonResult<List<String>> jsonResult = new JsonResult<>();
        List<String> ids = baseChannelDao.findChildrenIdsById(id);
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(ids);
        return jsonResult;
    }

    public JsonResult<List<String>> findBaseChannelList(BaseChannelCustomerRequest baseChannelCustomerRequest) {
        JsonResult<List<String>> jsonResult = new JsonResult<>();
        List<String> ids = baseChannelDao.findBaseChannelList(baseChannelCustomerRequest);
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(ids);
        return jsonResult;
    }

    /**
     * 查询上级渠道属性
     *
     * @param channelId
     * @return JsonResult<List<String>>
     */
    public JsonResult<List<String>> findParentType(List<String> channelId) {
        JsonResult<List<String>> jsonResult = new JsonResult<>();
        List<String> customerTypes = baseChannelDao.findParentType(channelId);
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(customerTypes);
        return jsonResult;
    }

    public JsonResult<BaseChannelDto> findParent(BaseChannelCustomerRequest baseChannelCustomerRequest) {
        JsonResult<BaseChannelDto> jsonResult = new JsonResult<>();
        BaseChannel baseChannel = baseChannelDao.findParent(baseChannelCustomerRequest);
        if (Objects.isNull(baseChannel)) {
            return jsonResult.setCode(HttpStatusEnum.RECORD_NOT_EXIST.getCode()).setMsg(HttpStatusEnum.RECORD_NOT_EXIST.getMessage());
        }
        BaseChannelDto baseChannelDto = new BaseChannelDto();
        BeanUtils.copyProperties(baseChannel, baseChannelDto);
        return jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(baseChannelDto);
    }
}
